home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
6366
/
6366.xpi
/
chrome
/
firegestures.jar
/
content
/
firegestures
/
prefs.js
< prev
next >
Wrap
Text File
|
2009-11-17
|
19KB
|
594 lines
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const TYPE_CATEGORY = Ci.xdIGestureMapping.TYPE_CATEGORY;
const TYPE_NORMAL = Ci.xdIGestureMapping.TYPE_NORMAL;
const TYPE_SCRIPT = Ci.xdIGestureMapping.TYPE_SCRIPT;
const kTypeCol = 0;
const kNameCol = 1;
const kCommandCol = 2;
const kDirectionCol = 3;
const kFlagsCol = 4;
const kExtraArray1 = [
["wheelGestureU", "wheel-up" ],
["wheelGestureD", "wheel-down" ],
["rockerGestureL", "rocker-left" ],
["rockerGestureR", "rocker-right"],
];
const kExtraArray2 = [
["keypressGestureC", "keypress-ctrl" ],
["keypressGestureS", "keypress-shift"],
];
const FG_TYPE_ATTR = "_command-type";
const PREFS_DOMAIN = "extensions.firegestures.";
const DRAGDROP_FLAVOR = "text/x-moz-tree-index";
const APP_VERSION = parseFloat(Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).version);
var gMappingArray = [];
var gMappingView = null;
var gShouldCommit = false;
var PrefsUI = {
_gestureSvc: null,
_gestureMapping: null,
get promptSvc() {
return Cc["@mozilla.org/embedcomp/prompt-service;1"].
getService(Ci.nsIPromptService);
},
init: function() {
this._gestureSvc = Cc["@xuldev.org/firegestures/service;1"].getService(Ci.xdIGestureService);
if ("arguments" in window) {
this._gestureMapping = this._gestureSvc.getMapping(window.arguments[0]);
document.title = this._gestureMapping.name + " : " + document.title;
document.documentElement.setAttribute("windowtype", window.name);
}
else
this._gestureMapping = this._gestureSvc.getMappingForBrowser();
gMappingArray = this._gestureMapping.getMappingArray();
gMappingArray = gMappingArray.filter(function(item) {
var flags = item[kFlagsCol];
if (flags && flags.indexOf("hidden") >= 0)
return false;
if (flags && /^min:firefox([\d\.]+)$/.test(flags) && parseFloat(RegExp.$1) > APP_VERSION)
return false;
if (flags && /^max:firefox([\d\.]+)$/.test(flags) && parseFloat(RegExp.$1) < APP_VERSION)
return false;
return /^[LRUD]*$/.test(item[kDirectionCol]);
});
var mappingTree = document.getElementById("mappingTree");
gMappingView = new CustomTreeView();
mappingTree.view = gMappingView;
this.updateCommands();
this.rebuildExtraMenus1();
this.rebuildExtraMenus2();
var elt = document.getElementById("getScripts");
if (elt) {
var refChild = document.documentElement.getButton("extra2");
refChild.parentNode.insertBefore(elt, refChild);
}
if (navigator.platform.indexOf("Mac") == 0) {
elt.style.margin = "10px";
setTimeout(function() { window.sizeToContent(); }, 0);
}
},
done: function() {
if (gShouldCommit) {
for each (let [id, direction] in kExtraArray1) {
var menuList = document.getElementById(id);
var type = parseInt(menuList.selectedItem.getAttribute(FG_TYPE_ATTR), 10);
gMappingArray.push([type, menuList.label, menuList.value, direction]);
}
for each (let [id, direction] in kExtraArray2) {
var menuList = document.getElementById(id);
gMappingArray.push([TYPE_NORMAL, menuList.label, menuList.value, direction]);
}
try {
this._gestureMapping.saveUserMapping(gMappingArray);
}
catch(ex) {
var msg = "An error occurred while saving gesture mappings.\n\n" + ex;
this.promptSvc.alert(window, "FireGestures", msg);
}
}
this._gestureMapping = null;
this._gestureSvc = null;
},
rebuildExtraMenus1: function() {
for each (let [id, direction] in kExtraArray1) {
var menuList = document.getElementById(id);
var commandName = null;
var commandValue = null;
if (menuList.itemCount == 0) {
var command = this._gestureMapping.getCommandForDirection(direction);
if (command) {
commandName = command.name;
commandValue = command.value;
}
}
else {
commandName = menuList.selectedItem.label;
commandValue = menuList.selectedItem.value;
menuList.removeAllItems();
}
menuList.appendItem("...", "").setAttribute(FG_TYPE_ATTR, TYPE_NORMAL);
var selItem = null;
for each (let [type, name, command] in gMappingArray) {
if (type == TYPE_CATEGORY) {
var newItem = document.getElementById("separatorTemplate").cloneNode(true);
newItem.id = null;
newItem.firstChild.setAttribute("value", name);
menuList.menupopup.appendChild(newItem);
}
else {
var newItem = menuList.appendItem(name, command);
newItem.setAttribute(FG_TYPE_ATTR, type);
if ((commandName || commandValue) && !selItem) {
if ((type == TYPE_NORMAL && command == commandValue) ||
(type == TYPE_SCRIPT && name == commandName))
selItem = newItem;
}
}
}
menuList.selectedItem = selItem || menuList.getItemAtIndex(0);
}
},
rebuildExtraMenus2: function() {
for each (let [id, direction] in kExtraArray2) {
var menuList = document.getElementById(id);
var command = this._gestureMapping.getCommandForDirection(direction);
if (!command)
continue;
var elts = menuList.getElementsByAttribute("value", command.value);
if (elts.length > 0)
menuList.selectedItem = elts[0];
}
},
updateGroupedUI: function(aGroupName) {
var pref = document.getElementById(aGroupName).getAttribute("preference");
var val = document.getElementById(pref).value;
var enable = false;
switch (typeof(val)) {
case "boolean": enable = val;
case "number" : enable = val != 0;
case "string" : enable = val != "0";
}
Array.forEach(document.getElementsByAttribute("group", aGroupName), function(elt) {
elt.disabled = !enable;
if (elt.localName == "colorpicker")
elt.style.MozOpacity = enable ? "1" : "0.5";
});
if (aGroupName == "mouseTrail")
this.updateMouseTrailSample();
else if (aGroupName == "gestureTimeout")
return enable;
},
updateTriggerButton: function() {
var button = document.getElementById("extensions.firegestures.trigger_button").value;
["wheelUpLabel", "wheelDownLabel"].forEach(function(id) {
var label = document.getElementById(id);
label.value = label.getAttribute("value" + button);
});
window.sizeToContent();
},
updateMouseTrailSample: function() {
var elt = document.getElementById("mouseTrailSample");
var size = document.getElementById(PREFS_DOMAIN + "mousetrail.size").value;
elt.style.borderWidth = size.toString() + "px";
elt.style.borderColor = document.getElementById(PREFS_DOMAIN + "mousetrail.color").value;
if (document.getElementById("extensions.firegestures.mousetrail").value)
elt.previousSibling.disabled = (size == 1);
},
changeMouseTrailSize: function(aIncrement) {
var pref = document.getElementById(PREFS_DOMAIN + "mousetrail.size");
pref.value = pref.value + aIncrement > 0 ? pref.value + aIncrement : 1;
this.updateMouseTrailSample();
},
generateMappingsMenu: function(event) {
var menuPopup = event.target;
if (menuPopup.hasAttribute("_generated"))
return;
menuPopup.setAttribute("_generated", "true");
for each (let { id: id, name: name } in this._gestureSvc.getMappingsInfo()) {
var menuItem = document.createElement("menuitem");
menuItem.setAttribute("id", id);
menuItem.setAttribute("label", name);
menuPopup.appendChild(menuItem);
}
},
backupMappings: function(aMenuItem) {
var dbConn = this._gestureSvc.getDBConnection(false);
if (!dbConn)
return;
var filePicker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
filePicker.init(window, aMenuItem.getAttribute("title"), filePicker.modeSave);
filePicker.appendFilter("SQLite", "*.sqlite");
var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
filePicker.displayDirectory = dirSvc.get("Desk", Ci.nsILocalFile);
var date = new Date().toLocaleFormat("%Y-%m-%d");
filePicker.defaultString = dbConn.databaseFile.leafName.replace(".", "-" + date + ".");
if (filePicker.show() == filePicker.returnCancel || !filePicker.file)
return;
var file = filePicker.file.QueryInterface(Ci.nsILocalFile);
this._gestureSvc.backupMappings(file);
},
restoreMappings: function(aMenuItem) {
var filePicker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
filePicker.init(window, aMenuItem.getAttribute("title"), filePicker.modeOpen);
filePicker.appendFilter("SQLite", "*.sqlite");
if (filePicker.show() == filePicker.returnCancel || !filePicker.file)
return;
if (!this.promptSvc.confirm(window, "FireGestures", aMenuItem.getAttribute("alerttext")))
return;
var file = filePicker.file.QueryInterface(Ci.nsILocalFile);
this._gestureSvc.restoreMappings(file);
},
handleTreeEvent: function(event) {
if (event.type == "dblclick") {
if (event.target.localName == "treechildren")
this.doCommand("cmd_edit_gesture");
}
else if (event.type == "keypress") {
switch (event.keyCode) {
case event.DOM_VK_RETURN:
this.doCommand("cmd_edit_gesture");
break;
case event.DOM_VK_DELETE:
this.doCommand("cmd_clear_gesture");
break;
default: return;
}
event.preventDefault();
}
},
updateCommands: function() {
var idxs = gMappingView.getSelectedIndexes();
var canEdit = idxs.length > 0;
var canDelete = false, canClear = false;
idxs.forEach(function(idx) {
if (gMappingArray[idx][kTypeCol] == TYPE_SCRIPT)
canDelete = true;
if (gMappingArray[idx][kDirectionCol])
canClear = true;
});
var setElementDisabledByID = function(aID, aDisable) {
if (aDisable)
document.getElementById(aID).removeAttribute("disabled");
else
document.getElementById(aID).setAttribute("disabled", "true");
};
setElementDisabledByID("cmd_edit_gesture", canEdit);
setElementDisabledByID("cmd_clear_gesture", canClear);
setElementDisabledByID("cmd_delete_script", canDelete);
},
doCommand: function(aCommand) {
switch (aCommand) {
case "cmd_add_script":
var suggestedName = document.getElementById("bundleMain").getString("NEW_SCRIPT");
var nums = [0];
gMappingArray.forEach(function(item) {
if (item[kNameCol].indexOf(suggestedName) == 0 && /\s\((\d+)\)$/.test(item[kNameCol]))
nums.push(parseInt(RegExp.$1, 10));
});
suggestedName += " (" + (Math.max.apply(this, nums) + 1) + ")";
var newIdx = gMappingView.appendItem([TYPE_SCRIPT, suggestedName, "", ""]);
this.editGesture(newIdx, true);
break;
case "cmd_edit_gesture" :
var idxs = gMappingView.getSelectedIndexes();
idxs.forEach(function(idx) { this.editGesture(idx, false); }, this);
break;
case "cmd_clear_gesture":
var idxs = gMappingView.getSelectedIndexes();
idxs.forEach(function(idx) { gMappingArray[idx][kDirectionCol] = ""; });
gMappingView.update();
break;
case "cmd_delete_script":
var idxs = gMappingView.getSelectedIndexes();
for (var i = idxs.length - 1; i >= 0; i--) {
if (gMappingArray[idxs[i]][kTypeCol] == TYPE_SCRIPT)
gMappingView.removeItemAt(idxs[i]);
}
this.rebuildExtraMenus1();
break;
}
this.updateCommands();
gShouldCommit = true;
},
editGesture: function(aIdx, aIsNewScript) {
var oldCommand = gMappingArray[aIdx][kCommandCol];
var oldDirection = gMappingArray[aIdx][kDirectionCol];
var ret = {
type : gMappingArray[aIdx][kTypeCol],
name : gMappingArray[aIdx][kNameCol],
command : oldCommand,
direction: oldDirection,
accepted : false
};
var features = "chrome,modal" + (ret.type == TYPE_SCRIPT ? ",all,resizable" : "");
document.documentElement.openSubDialog("chrome://firegestures/content/edit.xul", features, ret);
if (!ret.accepted) {
if (aIsNewScript)
gMappingView.removeItemAt(aIdx);
return;
}
if (this.checkConflict(ret.direction, aIdx)) {
if (aIsNewScript)
ret.direction = "";
else if (oldCommand != ret.command)
ret.direction = oldDirection;
else
return;
}
gMappingArray[aIdx][kDirectionCol] = ret.direction;
if (ret.type == TYPE_SCRIPT) {
gMappingArray[aIdx][kNameCol] = ret.name;
gMappingArray[aIdx][kCommandCol] = ret.command;
}
this.rebuildExtraMenus1();
gMappingView.update();
},
checkConflict: function(aDirection, aIdx) {
if (!aDirection)
return false;
for (var i = 0; i < gMappingArray.length; i++) {
var item = gMappingArray[i];
if (i != aIdx && item[kDirectionCol] == aDirection) {
var msg = document.getElementById("bundleMain").getFormattedString(
"CONFIRM_CONFLICT",
[aDirection, item[kNameCol], item[kNameCol]]
);
var ret = this.promptSvc.confirmEx(
window, "FireGestures", msg, this.promptSvc.STD_YES_NO_BUTTONS,
null, null, null, null, {}
);
if (ret == 1)
return true;
item[kDirectionCol] = "";
return false;
}
}
return false;
},
openURL: function(aURL) {
var win = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator)
.getMostRecentWindow("navigator:browser");
if (win)
win.gBrowser.loadOneTab(aURL, null, null, null, false, false);
else
window.open(aURL);
}
};
var gDragDropObserver = {
onDragStart: function(event, aXferData, aDragAction) {
var selIdxs = gMappingView.getSelectedIndexes();
if (selIdxs.length != 1)
return;
var sourceIndex = selIdxs[0];
if (gMappingArray[sourceIndex][kTypeCol] != TYPE_SCRIPT)
return;
aXferData.data = new TransferData();
aXferData.data.addDataForFlavour(DRAGDROP_FLAVOR, sourceIndex);
aDragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_MOVE;
},
_flavourSet: null,
getSupportedFlavours: function() {
if (!this._flavourSet) {
this._flavourSet = new FlavourSet();
this._flavourSet.appendFlavour("text/x-moz-url");
}
return this._flavourSet;
},
canDrop: function(event, aDragSession) { return true; },
onDragEnter: function(event, aDragSession) {},
onDragOver: function(event, aFlavour, aDragSession) {},
onDragExit: function(event, aDragSession) {},
onDrop: function(event, aXferData, aDragSession) {
const URL_PREFIX = "data:text/javascript,";
var lines = aXferData.data.toString().split("\n");
if (lines.length != 2 || lines[0].indexOf(URL_PREFIX) != 0)
return;
lines[0] = decodeURIComponent(lines[0].substr(URL_PREFIX.length));
gMappingView.appendItem([TYPE_SCRIPT, lines[1], lines[0], ""]);
PrefsUI.rebuildExtraMenus1();
gShouldCommit = true;
},
};
function CustomTreeView() {}
CustomTreeView.prototype = {
get ATOM_SVC() {
if (!this._atomSvc)
this._atomSvc = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService);
return this._atomSvc;
},
_atomSvc: null,
_treeBoxObject: null,
appendItem: function(aItem) {
gMappingArray.push(aItem);
var newIdx = this.rowCount - 1;
this._treeBoxObject.rowCountChanged(newIdx, 1);
this.selection.select(newIdx);
this._treeBoxObject.ensureRowIsVisible(newIdx);
this._treeBoxObject.treeBody.focus();
return newIdx;
},
removeItemAt: function(aIndex) {
gMappingArray.splice(aIndex, 1);
this._treeBoxObject.rowCountChanged(aIndex, -1);
},
moveItem: function(aSourceIndex, aTargetIndex) {
var removedItems = gMappingArray.splice(aSourceIndex, 1);
gMappingArray.splice(aTargetIndex, 0, removedItems[0]);
gShouldCommit = true;
},
update: function() {
this._treeBoxObject.invalidate();
},
getSelectedIndexes: function() {
var ret = [];
var sel = this.selection;
for (var rc = 0; rc < sel.getRangeCount(); rc++) {
var start = {}, end = {};
sel.getRangeAt(rc, start, end);
for (var idx = start.value; idx <= end.value; idx++) {
if (!this.isSeparator(idx))
ret.push(idx);
}
}
return ret;
},
getSourceIndexFromDrag: function() {
var dragService = Cc["@mozilla.org/widget/dragservice;1"].getService(Ci.nsIDragService);
var dragSession = dragService.getCurrentSession();
var xferData = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
xferData.addDataFlavor(DRAGDROP_FLAVOR);
dragSession.getData(xferData, 0);
var obj = {}, len = {};
var sourceIndex = -1;
try {
xferData.getAnyTransferData({}, obj, len);
}
catch (ex) {}
if (obj.value) {
sourceIndex = obj.value.QueryInterface(Ci.nsISupportsString).data;
sourceIndex = parseInt(sourceIndex.substring(0, len.value), 10);
}
return sourceIndex;
},
get rowCount() {
return gMappingArray.length;
},
selection: null,
getRowProperties: function(index, properties) {},
getCellProperties: function(row, col, properties) {
if (col.index == 0 && this.isSeparator(row))
properties.AppendElement(this.ATOM_SVC.getAtom("category"));
},
getColumnProperties: function(col, properties) {},
isContainer: function(index) { return false; },
isContainerOpen: function(index) { return false; },
isContainerEmpty: function(index) { return false; },
isSeparator: function(index) {
return gMappingArray[index][kTypeCol] == TYPE_CATEGORY;
},
isSorted: function() { return false; },
canDrop: function(targetIndex, orientation) {
var sourceIndex = this.getSourceIndexFromDrag();
return (
gMappingArray[targetIndex][kTypeCol] == TYPE_SCRIPT &&
sourceIndex != -1 &&
sourceIndex != targetIndex &&
sourceIndex != (targetIndex + orientation)
);
},
drop: function(targetIndex, orientation) {
var sourceIndex = this.getSourceIndexFromDrag();
if (sourceIndex == -1)
return;
if (sourceIndex < targetIndex) {
if (orientation == Ci.nsITreeView.DROP_BEFORE)
targetIndex--;
}
else {
if (orientation == Ci.nsITreeView.DROP_AFTER)
targetIndex++;
}
this.moveItem(sourceIndex, targetIndex);
this.update();
this.selection.clearSelection();
this.selection.select(targetIndex);
},
getParentIndex: function(rowIndex) { return -1; },
hasNextSibling: function(rowIndex, afterIndex) { return false; },
getLevel: function(index) { return 0; },
getImageSrc: function(row, col) {},
getProgressMode: function(row, col) {},
getCellValue: function(row, col) {},
getCellText: function(row, col) {
switch (col.index) {
case 0: return gMappingArray[row][kNameCol];
case 1: return gMappingArray[row][kCommandCol].replace(/\r|\n|\t/g, " ");
case 2: return gMappingArray[row][kDirectionCol];
}
},
setTree: function(tree) {
this._treeBoxObject = tree;
},
toggleOpenState: function(index) {},
cycleHeader: function(col) {},
selectionChanged: function() {},
cycleCell: function(row, col) {},
isEditable: function(row, col) { return false; },
isSelectable: function(row, col) {},
setCellValue: function(row, col, value) {},
setCellText: function(row, col, value) {
if (col.index == 0)
gMappingArray[row][kNameCol] = value;
else if (col.index == 1)
gMappingArray[row][kCommandCol] = value;
else if (col.index == 2)
gMappingArray[row][kDirectionCol] = value;
},
performAction: function(action) {},
performActionOnRow: function(action, row) {},
performActionOnCell: function(action, row, col) {},
};